package com.bidding.common.model;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * 统一响应结构
 */
@Data
@ApiModel(value = "统一响应结果", description = "API响应的统一封装格式")
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "状态码", example = "200")
    private Integer code;

    @ApiModelProperty(value = "返回消息", example = "操作成功")
    private String message;

    @ApiModelProperty(value = "返回数据")
    private T data;

    /**
     * 私有构造方法，禁止直接创建
     */
    private Result() {
    }

    /**
     * 成功返回结果
     *
     * @param data 返回数据
     * @param <T>  数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> success(T data) {
        return success(data, "操作成功");
    }

    /**
     * 成功返回结果
     *
     * @param data    返回数据
     * @param message 返回消息
     * @param <T>     数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> success(T data, String message) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage(message);
        result.setData(data);
        return result;
    }

    /**
     * 失败返回结果
     *
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> error(String message) {
        return error(500, message);
    }

    /**
     * 失败返回结果
     *
     * @param code    错误码
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> error(Integer code, String message) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMessage(message);
        return result;
    }

    /**
     * 参数验证失败返回结果
     *
     * @param message 提示信息
     * @param <T>     数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> validateFailed(String message) {
        return error(400, message);
    }

    /**
     * 未登录返回结果
     *
     * @param <T> 数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> unauthorized() {
        return error(401, "暂未登录或token已过期");
    }

    /**
     * 未授权返回结果
     *
     * @param <T> 数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> forbidden() {
        return error(403, "没有相关权限");
    }

    /**
     * 失败返回结果 - 用于替代原先的fail方法
     *
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> fail(String message) {
        return error(message);
    }

    /**
     * 失败返回结果 - 用于替代原先的fail方法
     *
     * @param code    错误码
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> fail(Integer code, String message) {
        return error(code, message);
    }

    /**
     * 登录失效返回结果
     *
     * @param <T> 数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> tokenInvalid() {
        return error(401, "登录已失效，请重新登录");
    }

    /**
     * 登录被顶下线返回结果
     *
     * @param <T> 数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> tokenReplaced() {
        return error(401, "您的账号已在其他设备登录，如非本人操作，请立即修改密码");
    }

    /**
     * 无权限访问返回结果
     *
     * @param permission 缺少的权限标识
     * @param <T>        数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> noPermission(String permission) {
        return error(403, "无权限访问：" + permission);
    }

    /**
     * 角色不足返回结果
     *
     * @param role 缺少的角色
     * @param <T>  数据类型
     * @return 统一响应结果
     */
    public static <T> Result<T> noRole(String role) {
        return error(403, "角色不足：" + role);
    }
}